from django.db import models
from django.utils import timezone


class SysTableMapping(models.Model):
    """
    数据库表名映射表（管理通用表与院内表的对应关系）
    """
    id = models.BigAutoField(primary_key=True, verbose_name="主键ID")
    common_table_name = models.CharField(
        max_length=100,
        verbose_name="通用表名（标准化表名）"
    )
    hospital_table_name = models.CharField(
        max_length=100,
        verbose_name="院内表名（医院实际使用的表名）"
    )
    database_name = models.CharField(
        max_length=50,
        verbose_name="对应数据库名称（表所在的数据库）"
    )
    database_dict_id = models.BigIntegerField(
        null=True,
        blank=True,
        verbose_name="对应数据库的字典ID（关联数据库字典表的主键）"
    )
    table_description = models.TextField(
        null=True,
        blank=True,
        verbose_name="表解释（表的功能说明）"
    )
    created_at = models.DateTimeField(
        default=timezone.now,
        editable=False,
        verbose_name="创建时间"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="更新时间"
    )

    class Meta:
        verbose_name = "数据库表名映射"
        verbose_name_plural = "数据库表名映射"
        db_table = "sys_table_mapping"
        # 唯一索引：同一数据库内通用表名唯一
        unique_together = [
            ["common_table_name", "database_name"],
            ["hospital_table_name", "database_name"]
        ]
        # 普通索引
        indexes = [
            models.Index(fields=["database_dict_id"], name="idx_database_dict")
        ]

    def __str__(self):
        return f"{self.common_table_name} -> {self.hospital_table_name}"


class SysFieldMapping(models.Model):
    """
    表字段映射表（管理通用英文字段、院内英文字段与中文名称的对应关系）
    """
    id = models.BigAutoField(primary_key=True, verbose_name="主键ID")
    common_field_name = models.CharField(
        max_length=100,
        verbose_name="通用字段名（标准化英文字段名，如PERSONAL_ID）"
    )
    hospital_field_name = models.CharField(
        max_length=100,
        verbose_name="院内字段名（医院实际使用的英文字段名）"
    )
    table_mapping_id = models.ForeignKey(
        SysTableMapping,
        on_delete=models.PROTECT,  # 保护模式，防止删除被引用的表映射记录
        related_name="field_mappings",  # 反向关联名称，便于通过表映射查询字段映射
        db_column="table_mapping_id",
        verbose_name="关联的表名映射ID"
    )
    field_chinese_name = models.CharField(
        max_length=200,
        verbose_name="字段中文名（字段的中文名称，如“患者唯一ID号”）"
    )
    field_description = models.TextField(
        null=True,
        blank=True,
        verbose_name="字段解释（字段含义、业务规则说明）"
    )
    data_type = models.CharField(
        max_length=50,
        null=True,
        blank=True,
        verbose_name="字段数据类型（如VARCHAR2(100)、DATE等）"
    )
    is_required = models.BooleanField(
        default=False,
        verbose_name="是否必填（0-非必填，1-必填）"
    )
    created_at = models.DateTimeField(
        default=timezone.now,
        editable=False,
        verbose_name="创建时间"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="更新时间"
    )

    class Meta:
        verbose_name = "表字段映射"
        verbose_name_plural = "表字段映射"
        db_table = "sys_field_mapping"
        # 唯一约束
        unique_together = [
            ["common_field_name", "table_mapping_id"],  # 同一表内通用字段名唯一
            ["hospital_field_name", "table_mapping_id"]  # 同一表内院内字段名唯一
        ]
        # 普通索引
        indexes = [
            models.Index(fields=["table_mapping_id"], name="idx_table_mapping")
        ]

    def __str__(self):
        return f"{self.common_field_name} -> {self.hospital_field_name}"

